package gameUI;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JPanel;

public class GamePanel extends JPanel {
	/* 获取图片 */
	BufferedImage img;
	/* 随机数方法 */
	Random ran = new Random();
	/* 初始化英雄战机 */
	Hero hero = new Hero();
	/* 初始化敌机大本营 */
	List<Ep> eps = new ArrayList<Ep>();
	/* 初始化游戏分数 */
	int score = 0;
	/* 初始化游戏是否结束 默认未结束false */
	boolean isFail = false;
	/* 游戏暂停 */

	public GamePanel() {
		/* 获取背景图 */
		img = ImageTools.getimage("../img/bg1.jpg");

		/* 创建鼠标监听，使战机动起来 */
		MouseAdapter mouse = new MouseAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				int mx = e.getX();// 获取鼠标横坐标
				int my = e.getY();// 获取鼠标纵坐标
				/* 如果游戏没有结束才修改位置信息 */
				if (!isFail) {
					/* 修改英雄战机的位置 */
					hero.move(mx, my);
				}

				/* 重绘 */
				repaint();
			}

			@Override
			public void mouseClicked(MouseEvent e) {
				/* 如果游戏结束了，点击重新加载 */
				if (isFail) {
					/* 游戏初始化 */
					/* 随机背景图 */
					img = ImageTools.getimage("../img/bg" + (ran.nextInt(4) + 1) + ".jpg");
					/* 初始化英雄战机 */
					hero = new Hero();
					/* 初始化敌机大本营 */
					eps.clear();
					/* 初始化游戏分数 */
					score = 0;
					/* 初始化子弹库 */
					hero.fires.clear();
					/* 修改难度 */
					index = 0;
					rank = 20;
					number = 1;
					/* 修改游戏状态 */
					isFail = false;

					repaint();
				}
				repaint();
			}
		};
		/* 注册监听 */
		addMouseMotionListener(mouse);// 移动事件需要的
		addMouseListener(mouse);// 点击事件需要
	}

	/**
	 * 游戏开始的方法
	 */
	public void start() {
		/* 创建删除死亡敌机的线程 */
		new Thread() {
			@Override
			public void run() {
				while (true) {
					/* 遍历敌机 */
					for (int i = 0; i < eps.size(); i++) {
						Ep e = eps.get(i);
						if (e.isDie) {
							/* 如果死亡就删除敌机 */
							eps.remove(e);
						}
					}
					/* 让死亡的图片显示0.5s */
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

		/* 游戏逻辑线程 */
		/* 创建多线程 */
		new Thread() {
			@Override
			public void run() {
				/* 不断运行 */
				while (true) {
					/* 如果游戏没有结束false才运行 */
					if (!isFail) {
						/* 创建敌机的方法 */
						createEp();
						/* 敌机移动的方法 */
						Epmove();
						/* 创建子弹 */
						hero.getFires();
						/* 子弹飞起来 */
						Firemove();
						/* 子弹碰撞敌机 */
						hitRemove();
						/* 判断游戏是否结束 */
						gameOver();
					}

					try {
						Thread.sleep(25);
						repaint();// 重绘
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
		}.start();
	}

	/**
	 * 判断英雄战机有没有与敌机发生碰撞
	 */
	protected void gameOver() {
		/* 与敌机碰撞，所以要判断敌机和英雄机之间的关系 */
		for (int i = 0; i < eps.size(); i++) {
			Ep e = eps.get(i);// 获取敌机
			/* 如果碰撞了,并且敌机处于非死亡状态 */
			if (hero.hit(e) && !e.isDie) {
				/* 修改敌机的状态 */
				e.isDie = true;
				e.showDie();
				/* 英雄的血量减少 */
				hero.hp--;
				/* 血量减少一次就判断难度是否小于20 如果小于20大于15，那么回升1 */
				if (rank < 20 && rank >= 15) {
					rank += 1;
				} else if (rank < 15 && rank >= 10) {// 小于15大于10回升2
					rank += 2;
				} else if (rank < 10) {// 小于10大于5回升3
					rank += 3;
				}
				/* 如果弹道大于0并且血量小于等于4 */
				/* 那么英雄机火力-1 */
				if (hero.grade > 0 && hero.grade <= 4) {
					hero.grade--;
				}
				/* 敌机死亡 */
				// eps.remove(e);
				/* 扣除分数 */
				if (score >= 10) {
					score -= 10;
				}
				/* 如果血量为0 */
				if (hero.hp <= 0) {
					/* 那么游戏就结束 */
					isFail = true;
					return;
				}
			}
		}
	}

	/**
	 * 子弹飞起来
	 */
	protected void Firemove() {
		for (int i = 0; i < hero.fires.size(); i++) {
			Fire fire = hero.fires.get(i);// 获取子弹
			fire.move();// 调用方法
		}
	}

	/**
	 * 子弹碰撞敌机
	 */
	protected void hitRemove() {
		/* 先遍历所有的子弹 */
		for (int i = 0; i < hero.fires.size(); i++) {
			Fire f = hero.fires.get(i);// 获取一颗子弹
			/* 每拿到一颗子弹，就判断一下这颗子弹是否打中敌机 */
			bang(f);
		}
	}

	/**
	 * 判断子弹是否打中敌机
	 * 
	 * @param f
	 */
	private void bang(Fire f) {
		/* 遍历所有的敌机 */
		for (int i = 0; i < eps.size(); i++) {
			Ep e = eps.get(i);// 获取敌机
			// 判断子弹是否击中敌机
			if (f.hit(f, e) && !e.isDie) {
				/* 如果敌机被击中 */
				e.hp--;
				/* 如果血量为0 */
				if (e.hp <= 0) {
					/* 修改敌机状态 */
					e.isDie = true;
					e.showDie();
					/* 如果打中的是属性机 那么就增加弹道 */
					if (e.type == 12) {
						hero.grade++;
						/* 如果弹道大于等于5的时候是增加血量 */
						if (hero.grade >= 5) {
							/* 如果血量小于5的话才能增加血量 */
							if (hero.hp < 5) {
								hero.hp++;
							}
							hero.grade = 4;
						}
					}
					/* 1敌机死亡，从大本营中删除 */
					// eps.remove(e);
					/* 3分数增加 */
					score += 5;
				}
				/* 2删除子弹，从子弹库中删除 */
				hero.fires.remove(f);

			}
		}
	}

	/**
	 * 敌机移动的方法
	 */
	protected void Epmove() {
		for (int i = 0; i < eps.size(); i++) {
			Ep ep = eps.get(i);// 获取敌机
			ep.move();// 调用方法
		}
	}

	/**
	 * 创建敌机
	 */
	int index = 0;
	int rank = 20;// 游戏难度

	protected void createEp() {
		index++;
		/* 如果调用20次方法才创建一次敌机 */
		if (index % rank == 0) {
			Ep e = new Ep();
			eps.add(e);// 将创建的敌机加入到大本营
		}
		/* 判断如果分数每次增加100就提高一次难度 */
		setRank();
	}

	/**
	 * 修改难度的方法
	 */
	int number = 1;// 控制器

	private void setRank() {
		/* 用number来控制语句中的使用 */
		if (number == (score / 100)) {
			number++;
			/* 如果难度大于等于5才增加难度 */
			if (rank >= 5) {
				rank -= 2;
			}
		}
	}

	/**
	 * 绘画
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		/* 绘制背景 */
		g.drawImage(img, 0, 0, null);

		/* 绘制英雄战机 */
		g.drawImage(hero.img, hero.x, hero.y, hero.w, hero.h, null);

		/* 绘制敌机 */
		// g.drawImage(ep.img, ep.x, ep.y, ep.w, ep.h, null);
		for (int i = 0; i < eps.size(); i++) {
			Ep ep = eps.get(i);// 获取大本营中的敌机
			g.drawImage(ep.img, ep.x, ep.y, ep.w, ep.h, null);
			/* 如果不是导弹才进行绘制 */
			if (ep.type != 15 && ep.hp > 0) {
				/* 绘制敌机血量 */
				for (int j = 0; j < ep.hp; j++) {
					g.setColor(Color.red);
					g.fillRect(ep.x + ep.w / ep.Mhp * j + 1, ep.y, (ep.w / ep.Mhp) - 2, 5);
				}
			}
		}

		/* 绘制英雄机子弹 */
		// g.drawImage(fire.img, fire.x, fire.y, fire.w, fire.h, null);
		for (int i = 0; i < hero.fires.size(); i++) {
			Fire fire = hero.fires.get(i);// 获取子弹库中的子弹
			g.drawImage(fire.img, fire.x, fire.y, fire.w, fire.h, null);
		}

		/* 绘制分数面板 */
		g.setColor(Color.white);
		g.setFont(new Font("楷体", Font.BOLD, 30));
		g.drawString("分数：" + score, 10, 30);
		g.drawString("难度级别：" + (20 - rank), 10, 75);

		/* 如果游戏结束 那么就告知 */
		if (isFail) {
			g.setColor(Color.white);
			g.setFont(new Font("arial", Font.BOLD, 60));
			g.drawString("GAME OVER !", 50, 350);
			g.setFont(new Font("楷体", Font.BOLD, 40));
			g.drawString("单击鼠标重新开始游戏", 30, 430);
		}

		/* 绘制飞机血量 */
		for (int i = 0; i < hero.hp; i++) {
			g.drawImage(hero.img, 450, 10 + 35 * i, 30, 30, null);
		}
	}
}
